"""
视频显示组件
负责视频播放、控制和显示
"""

import cv2
import numpy as np
import time
from pathlib import Path

from PySide6.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QPushButton, 
    QLabel, QTabWidget
)
from PySide6.QtCore import Qt, QThread, Signal
from PySide6.QtGui import QPixmap, QImage


class VideoThread(QThread):
    """
    视频处理线程
    
    用于在后台处理视频流，避免阻塞UI
    """
    frameReady = Signal(np.ndarray)
    resultReady = Signal(dict)
    fpsUpdate = Signal(float)
    
    def __init__(self):
        super().__init__()
        self.is_running = False
        self.video_source = None
        self.detector = None
        self.recognizer = None
        self.processor = None
        self.skip_frames = 1
        self.frame_count = 0
        
    def set_models(self, detector, recognizer, processor):
        """设置模型"""
        self.detector = detector
        self.recognizer = recognizer
        self.processor = processor
        
    def set_source(self, source):
        """设置视频源"""
        self.video_source = source
        
    def run(self):
        """线程主函数"""
        if self.video_source is None:
            return
            
        # 打开视频源
        if isinstance(self.video_source, int):
            cap = cv2.VideoCapture(self.video_source)
        else:
            cap = cv2.VideoCapture(str(self.video_source))
            
        if not cap.isOpened():
            return
            
        self.is_running = True
        start_time = time.time()
        fps_counter = 0
        
        while self.is_running:
            ret, frame = cap.read()
            if not ret:
                break
                
            self.frame_count += 1
            
            # 跳帧处理
            if self.frame_count % self.skip_frames != 0:
                continue
                
            # 发送原始帧
            self.frameReady.emit(frame)
            
            # 检测和识别
            if self.detector and self.recognizer:
                detections = self.detector.detect(frame)
                
                for detection in detections:
                    bbox = detection['bbox']
                    # 提取车牌区域
                    plate_region = self.processor.extract_plate_region(frame, bbox)
                    
                    # 识别车牌
                    result = self.recognizer.recognize(plate_region)
                    
                    # 组合结果
                    full_result = {
                        'bbox': bbox,
                        'plate_number': result['text'],
                        'confidence': result['confidence'],
                        'timestamp': self._get_timestamp()
                    }
                    
                    self.resultReady.emit(full_result)
                    
            # 计算FPS
            fps_counter += 1
            if fps_counter >= 30:  # 每30帧更新一次
                elapsed = time.time() - start_time
                fps = fps_counter / elapsed
                self.fpsUpdate.emit(fps)
                fps_counter = 0
                start_time = time.time()
                
        cap.release()
        
    def stop(self):
        """停止线程"""
        self.is_running = False
        self.wait()
        
    def _get_timestamp(self):
        """获取时间戳"""
        from datetime import datetime
        return datetime.now().strftime("%Y-%m-%d %H:%M:%S")


class VideoDisplayWidget(QWidget):
    """
    视频显示组件
    
    功能：
    - 显示视频流
    - 控制视频播放
    - 处理视频检测结果
    """
    
    resultReady = Signal(dict)
    
    def __init__(self):
        super().__init__()
        self.video_thread = VideoThread()
        self.results = []
        self.init_ui()
        self.connect_signals()
        
    def init_ui(self):
        """初始化界面"""
        layout = QVBoxLayout(self)
        
        # 视频显示标签
        self.video_label = QLabel()
        self.video_label.setMinimumSize(640, 480)
        self.video_label.setStyleSheet("QLabel { background-color: black; }")
        self.video_label.setAlignment(Qt.AlignCenter)
        self.video_label.setText("等待视频输入...")
        layout.addWidget(self.video_label)
        
        # 控制按钮
        button_layout = QHBoxLayout()
        
        self.btn_play = QPushButton("播放")
        self.btn_play.clicked.connect(self.play_video)
        self.btn_play.setEnabled(False)
        button_layout.addWidget(self.btn_play)
        
        self.btn_pause = QPushButton("暂停")
        self.btn_pause.clicked.connect(self.pause_video)
        self.btn_pause.setEnabled(False)
        button_layout.addWidget(self.btn_pause)
        
        self.btn_stop = QPushButton("停止")
        self.btn_stop.clicked.connect(self.stop_video)
        self.btn_stop.setEnabled(False)
        button_layout.addWidget(self.btn_stop)
        
        layout.addLayout(button_layout)
        
    def connect_signals(self):
        """连接信号"""
        self.video_thread.frameReady.connect(self.update_frame)
        self.video_thread.resultReady.connect(self.handle_result)
        
    def set_models(self, detector, recognizer, processor):
        """设置检测模型"""
        self.video_thread.set_models(detector, recognizer, processor)
        
    def set_source(self, source):
        """设置视频源"""
        self.video_thread.set_source(source)
        self.btn_play.setEnabled(True)
        self.btn_pause.setEnabled(True)
        self.btn_stop.setEnabled(True)
        
    def play_video(self):
        """播放视频"""
        if not self.video_thread.is_running:
            self.video_thread.start()
            self.btn_play.setText("播放中...")
            self.btn_play.setEnabled(False)
            
    def pause_video(self):
        """暂停视频"""
        if self.video_thread.is_running:
            self.video_thread.stop()
            self.btn_play.setText("播放")
            self.btn_play.setEnabled(True)
        
    def stop_video(self):
        """停止视频"""
        self.video_thread.stop()
        self.video_label.clear()
        self.video_label.setText("等待视频输入...")
        self.btn_play.setText("播放")
        self.btn_play.setEnabled(False)
        self.btn_pause.setEnabled(False)
        self.btn_stop.setEnabled(False)
        
    def update_frame(self, frame):
        """更新视频帧"""
        # 绘制检测结果
        display_frame = frame.copy()
        for result in self.results[-10:]:  # 只显示最近的10个结果
            if 'bbox' in result:
                display_frame = self._draw_bbox(
                    display_frame, result['bbox'],
                    f"{result['plate_number']} ({result['confidence']:.2f})"
                )
                
        self._display_frame(display_frame)
        
    def handle_result(self, result):
        """处理检测结果"""
        self.results.append(result)
        self.resultReady.emit(result)
        
    def _display_frame(self, frame):
        """显示帧到界面"""
        # 转换颜色空间
        rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        
        # 创建QImage
        h, w, ch = rgb_frame.shape
        bytes_per_line = ch * w
        qt_image = QImage(rgb_frame.data, w, h, bytes_per_line, QImage.Format_RGB888)
        
        # 缩放显示
        pixmap = QPixmap.fromImage(qt_image)
        scaled_pixmap = pixmap.scaled(
            self.video_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation
        )
        
        self.video_label.setPixmap(scaled_pixmap)
        
    def _draw_bbox(self, image, bbox, text):
        """绘制检测框"""
        x1, y1, x2, y2 = bbox
        cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
        cv2.putText(image, text, (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
        return image 